package main

import (
	"fmt"
	"sync"
	"runtime"
)

/*自己阻塞自己*/
func main091() {
	ch := make(chan int, 0)

	/*	go func() {
			x := <- ch
			fmt.Println(x)
		}()*/

	ch <- 123
	x := <-ch
	fmt.Println(x)
}

/*[开塞露协程]开晚了*/
func main092() {
	ch := make(chan int)
	ch <- 666 //这里一直阻塞，运行不到下面
	go func() {
		<-ch //这里虽然创建了子go程用来读出数据，但是上面会一直阻塞运行不到下面
	}()
}

/*管道读写时,相互要求对方先读/写,自己在写/读,造成死锁*/
func main093() {

	chHusband := make(chan int, 0)
	chWife := make(chan int, 0)

	//老公
	go func() {
		for{
			select {
			//只要我有钱我就给你发红包
			case <- chHusband:
				chWife <- 123
				fmt.Println("老公：我已经给你发123元红包了")
			case chWife <- 1:
				fmt.Println("老公：我已经给你发1元红包了")
			}
		}

	}()

	//老婆
	select {
	//只要我有钱我就给你发红包
	case <- chWife:
		chHusband <- 123
		fmt.Println("老婆：我已经给你发123元红包了")
	}

	fmt.Println("THE END")

}

/*读写锁定相互阻塞,形成隐形死锁*/
func main() {

	var rwm09 sync.RWMutex
	ch := make(chan int, 0)

	//子协程负责写入
	go func() {
		//连锁都抢不到555...
		rwm09.Lock()
		ch <- 123
		rwm09.Unlock()
	}()

	go func() {
		//本协程负责读出
		rwm09.RLock()
		//只要读不到内容就永远阻塞
		x := <- ch
		fmt.Println("读到",x)
		rwm09.RUnlock()
	}()

	for {
		//通知垃圾回收器来清理垃圾(即使不叫也会定时清理)
		runtime.GC()
	}

}
